﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataEntity;
using System.Data.SqlClient;
using System.Data;
using System.Collections.ObjectModel;

namespace Model
{
    public class CommonModel
    {
        public int Save<T>(T entity)
        {
            string tablename = entity.GetType().FullName.Split(new char[] { '.' }).LastOrDefault();
            string head = "insert into " + tablename + " (";
            string rear = ") values (";
            //string param = string.Empty; 
            foreach (var c in entity.GetType().GetProperties())
            {
                if (c.Name.ToLower().Equals("id") || c.Name.ToLower().Equals("text"))
                    continue;
                object value = c.GetValue(entity, null);
                if (value == null)
                {
                    continue;
                }
                head += c.Name + ", ";
                rear += " @" + c.Name + ", ";
            }
            head = head.Trim().TrimEnd(new char[] { ',' });
            rear = rear.Trim().TrimEnd(new char[] { ',' });
            string sql = head + rear + ")";
            sql += "                    select @@identity";
            SqlCommand comm = new SqlCommand(sql);
            foreach (var p in entity.GetType().GetProperties())
            {
                if (p.Name.ToLower().Equals("id") || p.Name.ToLower().Equals("text"))
                    continue;
                object value = p.GetValue(entity, null);
                if (value == null)
                {
                    continue;
                }
                System.Data.SqlDbType? type= null;
                switch (p.PropertyType.ToString().ToLower())
                {
                    case "system.int32": type = System.Data.SqlDbType.Int;
                        break;
                    case "system.single":
                    case "system.float": type = System.Data.SqlDbType.Float;
                        break;
                    case "system.nullable`1[system.datetime]":
                    case "system.datetime":
                        type = System.Data.SqlDbType.DateTime;
                        break;
                   
                    case "system.string":
                   type = System.Data.SqlDbType.VarChar;
                        break;
                }
                if (type != null)
                {
                    comm.Parameters.Add("@" + p.Name, type);
                    comm.Parameters["@" + p.Name].Value = p.GetValue(entity, null);
                    if (type == System.Data.SqlDbType.VarChar)
                    {
                        comm.Parameters["@" + p.Name].Value = p.GetValue(entity, null).ToString();
                    }
                }
            }
            DataSet ds = ConnectionUtil.GetInstance().ExcuteQuery(comm);
            int id = Convert.ToInt32(ds.Tables[0].Rows[0][0].ToString());
            entity.GetType().GetProperty("ID").SetValue(entity, id, null);
            return id;
        }

        public void Update<T>(T entity)
        {
            string tablename = entity.GetType().FullName.Split(new char[] { '.' }).LastOrDefault();
            string sql = "update " + tablename + " set ";
           
            //string param = string.Empty;
            foreach (var c in entity.GetType().GetProperties())
            {
                if (c.Name.ToLower().Equals("id") || c.Name.ToLower().Equals("text"))
                    continue;
                object value = c.GetValue(entity, null);
                if (value == null)
                {
                    continue;
                }
                sql += c.Name + "= @" + c.Name + ", ";
            }
            sql = sql.Trim().TrimEnd(new char[] { ',' });

            sql += " where ID = " + entity.GetType().GetProperty("ID").GetValue(entity, null);
            SqlCommand comm = new SqlCommand(sql);
            foreach (var p in entity.GetType().GetProperties())
            {
                if (p.Name.Equals("ID") || p.Name.Equals("Text"))
                    continue;
                object value = p.GetValue(entity, null);
                if (value == null)
                {
                    continue;
                }
                System.Data.SqlDbType? type = null;
                switch (p.PropertyType.ToString().ToLower())
                {
                    case "system.int32": type = System.Data.SqlDbType.Int;
                        break;
                    case "system.single":
                    case "system.float": type = System.Data.SqlDbType.Float;
                        break;
                    case "system.nullable`1[system.datetime]":
                    case "system.datetime":
                        type = System.Data.SqlDbType.DateTime;
                        break;
                    case "system.string":
                    type = System.Data.SqlDbType.VarChar;
                        break;
                }
                if (type != null)
                {
                    comm.Parameters.Add("@" + p.Name, type);
                    comm.Parameters["@" + p.Name].Value = p.GetValue(entity, null);
                }
            }
            ConnectionUtil.GetInstance().ExcuteNonQuery(comm);
        }

        public ObservableCollection<T> Query<T>(string Condition) where T : new()
        {
            ObservableCollection<T> list = new ObservableCollection<T>();
            T entity = new T();
            string tablename = entity.GetType().FullName.Split(new char[] { '.' }).LastOrDefault();
            string sql = "select * from " + tablename;
            if (!string.IsNullOrEmpty(Condition))
                sql += " where " + Condition;
            SqlCommand comm = new SqlCommand(sql);
            DataSet ds = ConnectionUtil.GetInstance().ExcuteQuery(comm);
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                T e = new T();
                foreach (var p in entity.GetType().GetProperties())
                {
                    if ( p.Name.ToLower().Equals("text") ||row[p.Name].ToString().Equals(""))
                        continue;
                    switch (p.PropertyType.ToString().ToLower())
                    {
                        case "system.int32":
                            p.SetValue(e, Convert.ToInt32(row[p.Name].ToString()), null);
                            break;
                        case "system.single":
                        case "system.float": //type = System.Data.SqlDbType.Float;
                            p.SetValue(e, float.Parse(row[p.Name].ToString()), null);
                            break;
                        case "system.nullable`1[system.datetime]":
                        case "system.datetime":
                            //type = System.Data.SqlDbType.DateTime;
                            p.SetValue(e, DateTime.Parse(row[p.Name].ToString()), null);
                            break;
                        case "system.string":
                        p.SetValue(e, row[p.Name].ToString(), null); 
                            break;
                    }
                }
                list.Add(e);
            }
            return list;

        }

        public void delete(string tablename, string condition)
        {
            string sql = "delete " + tablename;
            if (!string.IsNullOrEmpty(condition))
            {
                sql += " where " + condition;
            }
            SqlCommand command = new SqlCommand(sql);
            ConnectionUtil.GetInstance().ExcuteNonQuery(command);
        }
    }
}

